﻿using Newtonsoft.Json;
using System.Xml;
using System.Xml.Linq;

namespace DoNet.Common.Helpers
{
    /// <summary>
    /// JSON序列化、反序列化扩展类。
    /// </summary>
    public static class JsonHelper
    {
        /// <summary>
        /// 将object 对象序列化为 JSON字符串
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string SerializeObject(object value)
        {
            return JsonConvert.SerializeObject(value);
        }

        /// <summary>
        /// 将object 对象序列化为 JSON字符串
        /// using a type, formatting and Newtonsoft.Json.JsonSerializerSettings
        /// </summary>
        /// <param name="value"></param>
        /// <param name="type"></param>
        /// <param name="formatting"></param>
        /// <param name="settings"></param>
        /// <returns></returns>
        public static string SerializeObject(object value, Type type, Newtonsoft.Json.Formatting formatting, JsonSerializerSettings settings)
        {
            return JsonConvert.SerializeObject(value, type, formatting, settings);
        }

        /// <summary>
        /// 将XmlNode转成字符串
        /// </summary>
        /// <param name="node">要序列化的节点</param>
        /// <returns></returns>
        public static string SerializeXmlNode(XmlNode node)
        {
            return JsonConvert.SerializeXmlNode(node);
        }

        /// <summary>
        /// 将XmlNode转成字符串
        /// </summary>
        /// <param name="node">要序列化的节点</param>
        /// <param name="formatting">指定输出的格式</param>
        /// <returns></returns>
        public static string SerializeXmlNode(XmlNode node, Newtonsoft.Json.Formatting formatting)
        {
            return JsonConvert.SerializeXmlNode(node, formatting);
        }

        /// <summary>
        /// 将XmlNode转成字符串
        /// using formatting and omits the root object if omitRootObject is true
        /// </summary>
        /// <param name="node">要序列化的节点</param>
        /// <param name="formatting">指定输出的格式</param>
        /// <param name="omitRootObject">省略写入根对象</param>
        /// <returns></returns>
        public static string SerializeXmlNode(XmlNode node, Newtonsoft.Json.Formatting formatting, bool omitRootObject)
        {
            return JsonConvert.SerializeXmlNode(node, formatting, omitRootObject);
        }

        /// <summary>
        /// 将XNode转成JSON字符串
        /// </summary>
        /// <param name="node">要转换为JSON的节点</param>
        /// <returns></returns>
        public static string SerializeXNode(XObject node)
        {
            return JsonConvert.SerializeXNode(node);
        }

        /// <summary>
        /// 将XNode转成JSON字符串
        /// using formatting
        /// </summary>
        /// <param name="node">要转换为JSON的节点</param>
        /// <param name="formatting">指定输出的格式</param>
        /// <returns></returns>
        public static string SerializeXNode(XObject node, Newtonsoft.Json.Formatting formatting)
        {
            return JsonConvert.SerializeXNode(node, formatting);
        }

        /// <summary>
        /// 将XNode转成JSON字符串
        /// using formatting and omits the root object if omitRootObject is true
        /// </summary>
        /// <param name="node">要转换为JSON的节点</param>
        /// <param name="formatting">指定输出的格式</param>
        /// <param name="omitRootObject">省略写入根对象</param>
        /// <returns></returns>
        public static string SerializeXNode(XObject node, Newtonsoft.Json.Formatting formatting, bool omitRootObject)
        {
            return JsonConvert.SerializeXNode(node, formatting, omitRootObject);
        }

        /// <summary>
        /// 将JSON字符串序列化为 object 对象
        /// </summary>
        /// <param name="value">要反序列化的JSON字符串</param>
        /// <returns></returns>
        public static object? DeserializeObject(string value)
        {
            return JsonConvert.DeserializeObject(value);
        }

        /// <summary>
        /// 将JSON字符串序列化为 object 对象
        /// using Newtonsoft.Json.JsonSerializerSettings
        /// </summary>
        /// <param name="value">要反序列化的JSON字符串</param>
        /// <param name="settings">用于反序列化对象。如果该值为空，则将使用默认序列化设置。</param>
        /// <returns></returns>
        public static object? DeserializeObject(string value, JsonSerializerSettings settings)
        {
            return JsonConvert.DeserializeObject(value, settings);
        }

        /// <summary>
        /// 将JSON字符串序列化为 object 对象
        /// Deserializes the JSON to the specified .NET type
        /// </summary>
        /// <param name="value">要反序列化的JSON字符串</param>
        /// <param name="type">The System.Type of object being deserialized.</param>
        /// <returns></returns>
        public static object? DeserializeObject(string value, Type type)
        {
            return JsonConvert.DeserializeObject(value, type);
        }

        /// <summary>
        /// 将JSON字符串序列化为对象
        /// Deserializes the JSON to the specified .NET type using a collection of Newtonsoft.Json.JsonConverter.
        /// </summary>
        /// <param name="value">要反序列化的JSON字符串</param>
        /// <param name="type">The System.Type of object being deserialized.</param>
        /// <param name="converters">反序列化时使用的转换器。</param>
        /// <returns></returns>
        public static object? DeserializeObject(string value, Type type, params Newtonsoft.Json.JsonConverter[] converters)
        {
            return JsonConvert.DeserializeObject(value, type, converters);
        }

        /// <summary>
        /// 将JSON字符串序列化为对象
        /// Deserializes the JSON to the specified .NET type using Newtonsoft.Json.JsonSerializerSettings.
        /// </summary>
        /// <param name="value">要反序列化的JSON字符串</param>
        /// <param name="type">The type of the object to deserialize to.</param>
        /// <param name="settings">用于反序列化对象。如果该值为空，则将使用默认序列化设置。</param>
        /// <returns></returns>
        public static object? DeserializeObject(string value, Type type, JsonSerializerSettings settings)
        {
            return JsonConvert.DeserializeObject(value, type, settings);
        }

        /// <summary>
        /// 将JSON字符串序列化为对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="value">要反序列化的JSON字符串</param>
        /// <returns></returns>
        public static T? DeserializeObject<T>(string value)
        {
            return JsonConvert.DeserializeObject<T>(value);
        }

        /// <summary>
        /// 将JSON字符串序列化为对象
        /// using Newtonsoft.Json.JsonSerializerSettings
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="value">要反序列化的JSON字符串</param>
        /// <param name="settings">用于反序列化对象。如果该值为空，则将使用默认序列化设置。</param>
        /// <returns></returns>
        public static T? DeserializeObject<T>(string value, JsonSerializerSettings settings)
        {
            return JsonConvert.DeserializeObject<T>(value, settings);
        }

        /// <summary>
        /// 将JSON字符串序列化为对象 
        /// using a collection of Newtonsoft.Json.JsonConverter.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="value">要反序列化的JSON字符串</param>
        /// <param name="converters">反序列化时使用的转换器。</param>
        /// <returns></returns>
        public static T? DeserializeObject<T>(string value, params Newtonsoft.Json.JsonConverter[] converters)
        {
            return JsonConvert.DeserializeObject<T>(value, converters);
        }

        /// <summary>
        /// 将JSON字符串序列化为XmlDocument对象 
        /// </summary>
        /// <param name="value">要反序列化的JSON字符串</param>
        /// <returns></returns>
        public static XmlDocument? DeserializeXmlNode(string value)
        {
            return JsonConvert.DeserializeXmlNode(value);
        }

        /// <summary>
        /// 将JSON字符串序列化为XmlDocument对象 
        /// nested in a root element specified by deserializeRootElementName
        /// </summary>
        /// <param name="value">要反序列化的JSON字符串</param>
        /// <param name="deserializeRootElementName">反序列化时要附加的根元素的名称。</param>
        /// <returns></returns>
        public static XmlDocument? DeserializeXmlNode(string value, string deserializeRootElementName)
        {
            return JsonConvert.DeserializeXmlNode(value, deserializeRootElementName);
        }

        /// <summary>
        /// 将JSON字符串序列化为XmlDocument对象 
        /// nested in a root element specified by deserializeRootElementName and writes a Json.NET array attribute for collections
        /// </summary>
        /// <param name="value">要反序列化的JSON字符串</param>
        /// <param name="deserializeRootElementName">反序列化时要附加的根元素的名称。</param>
        /// <param name="writeArrayAttribute">一个值，用于指示是否写入Json .NET数组属性。此属性有助于在将写入的XML转换回JSON时保留数组。</param>
        /// <returns></returns>
        public static XmlDocument? DeserializeXmlNode(string value, string deserializeRootElementName, bool writeArrayAttribute)
        {
            return JsonConvert.DeserializeXmlNode(value, deserializeRootElementName, writeArrayAttribute);
        }

        /// <summary>
        /// 将JSON字符串序列化为XmlDocument对象 
        /// nested in a root element specified by deserializeRootElementName, writes a Json.NET array attribute for collections, and encodes special characters
        /// </summary>
        /// <param name="value">要反序列化的JSON字符串</param>
        /// <param name="deserializeRootElementName">反序列化时要附加的根元素的名称。</param>
        /// <param name="writeArrayAttribute">一个值，用于指示是否写入Json .NET数组属性。此属性有助于在将写入的XML转换回JSON时保留数组。</param>
        /// <param name="encodeSpecialCharacters">一个值，用于指示在将JSON转换为XML时是否对特殊字符进行编码。如果为真，则使用特殊字符，如“：”、“@”、“？”、“#”JSON属性名中的“$”不用于指定XML命名空间、属性或处理指令。相反，特殊字符被编码并写入XML元素名称中。</param>
        /// <returns></returns>
        public static XmlDocument? DeserializeXmlNode(string value, string deserializeRootElementName, bool writeArrayAttribute, bool encodeSpecialCharacters)
        {
            return JsonConvert.DeserializeXmlNode(value, deserializeRootElementName, writeArrayAttribute, encodeSpecialCharacters);
        }

        /// <summary>
        /// 将JSON字符串序列化为XDocument对象 
        /// </summary>
        /// <param name="value">要反序列化的JSON字符串</param>
        /// <returns></returns>
        public static XDocument? DeserializeXNode(string value)
        {
            return JsonConvert.DeserializeXNode(value);
        }

        /// <summary>
        /// 将JSON字符串序列化为XDocument对象 
        /// </summary>
        /// <param name="value">要反序列化的JSON字符串</param>
        /// <param name="deserializeRootElementName">反序列化时要附加的根元素的名称</param>
        /// <returns></returns>
        public static XDocument DeserializeXNode(string value, string deserializeRootElementName)
        {
            return DeserializeXNode(value, deserializeRootElementName);
        }

        /// <summary>
        /// 将JSON字符串序列化为XDocument对象 
        /// </summary>
        /// <param name="value">要反序列化的JSON字符串</param>
        /// <param name="deserializeRootElementName">反序列化时要附加的根元素的名称</param>
        /// <param name="writeArrayAttribute">一个值，用于指示是否写入Json .NET数组属性。此属性有助于在将写入的XML转换回JSON时保留数组。</param>
        /// <returns></returns>
        public static XDocument DeserializeXNode(string value, string deserializeRootElementName, bool writeArrayAttribute)
        {
            return DeserializeXNode(value, deserializeRootElementName, writeArrayAttribute);
        }

        //
        // 摘要:
        //     Deserializes the System.Xml.Linq.XNode from a JSON string nested in a root element
        //     specified by deserializeRootElementName, writes a Json.NET array attribute for
        //     collections, and encodes special characters.
        //
        // 参数:
        //   value:
        //     The JSON string.
        //
        //   deserializeRootElementName:
        //     The name of the root element to append when deserializing.
        //
        //   writeArrayAttribute:
        //     A value to indicate whether to write the Json.NET array attribute. This attribute
        //     helps preserve arrays when converting the written XML back to JSON.
        //
        //   encodeSpecialCharacters:
        //     A value to indicate whether to encode special characters when converting JSON
        //     to XML. If true, special characters like ':', '@', '?', '#' and '$' in JSON property
        //     names aren't used to specify XML namespaces, attributes or processing directives.
        //     Instead special characters are encoded and written as part of the XML element
        //     name.
        //
        // 返回结果:
        //     The deserialized System.Xml.Linq.XNode.
        /// <summary>
        /// 将JSON字符串序列化为XDocument对象 
        /// nested in a root element specified by deserializeRootElementName, writes a Json.NET array attribute for collections, and encodes special characters
        /// </summary>
        /// <param name="value">要反序列化的JSON字符串</param>
        /// <param name="deserializeRootElementName">反序列化时要附加的根元素的名称。</param>
        /// <param name="writeArrayAttribute">一个值，用于指示是否写入Json .NET数组属性。此属性有助于在将写入的XML转换回JSON时保留数组。</param>
        /// <param name="encodeSpecialCharacters">一个值，用于指示在将JSON转换为XML时是否对特殊字符进行编码。如果为真，则使用特殊字符，如“：”、“@”、“？”、“#”JSON属性名中的“$”不用于指定XML命名空间、属性或处理指令。相反，特殊字符被编码并写入XML元素名称中。</param>
        /// <returns></returns>
        public static XDocument DeserializeXNode(string value, string deserializeRootElementName, bool writeArrayAttribute, bool encodeSpecialCharacters)
        {
            return DeserializeXNode(value, deserializeRootElementName, writeArrayAttribute, encodeSpecialCharacters);
        }

        /// <summary>
        /// 将JSON字符串序列化为给定的匿名类型对象
        /// </summary>
        /// <typeparam name="T">要反序列化到的匿名类型。传统上不能指定此类型，必须从作为参数传递的匿名类型中推断出来。</typeparam>
        /// <param name="value">要反序列化的JSON字符串</param>
        /// <param name="anonymousTypeObject">匿名类型对象</param>
        /// <returns></returns>
        public static T? DeserializeAnonymousType<T>(string value, T anonymousTypeObject)
        {
            return JsonConvert.DeserializeAnonymousType<T>(value, anonymousTypeObject);
        }

        /// <summary>
        /// 将JSON字符串序列化为给定的匿名类型对象
        /// using Newtonsoft.Json.JsonSerializerSettings
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="value">要反序列化的JSON字符串</param>
        /// <param name="anonymousTypeObject">匿名类型对象</param>
        /// <param name="settings">用于反序列化对象。如果该值为空，则将使用默认序列化设置。</param>
        /// <returns></returns>
        public static T? DeserializeAnonymousType<T>(string value, T anonymousTypeObject, JsonSerializerSettings settings)
        {
            return JsonConvert.DeserializeAnonymousType<T>(value, anonymousTypeObject, settings);
        }

        /// <summary>
        /// 用JSON字符串中的值填充对象
        /// </summary>
        /// <param name="value">用于填充值的JSON字符串</param>
        /// <param name="target">要填充值的目标对象。</param>
        public static void PopulateObject(string value, object target)
        {
            JsonConvert.PopulateObject(value, target);
        }

        /// <summary>
        /// 用JSON字符串中的值填充对象
        /// using Newtonsoft.Json.JsonSerializerSettings
        /// </summary>
        /// <param name="value">用于填充值的JSON字符串</param>
        /// <param name="target">要填充值的目标对象。</param>
        /// <param name="settings">用于反序列化对象。如果该值为空，则将使用默认序列化设置。</param>
        public static void PopulateObject(string value, object target, JsonSerializerSettings settings)
        {
            JsonConvert.PopulateObject(value, target, settings);
        }
    }
}
